﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System8Equations;
using System.Linq;

namespace System8ToyMC
{
	public partial class RandomVariableList : UserControl
	{
        /// <summary>
        /// Fired whenever something in our list has changed (and one
        /// might want to re-run the calc! :-)
        /// </summary>
        public event Action<S8Variable> VariableAdded;

        /// <summary>
        /// Called when the whole list of variables has been cleared out.
        /// </summary>
        public event Action VariablesCleared;

		public RandomVariableList()
		{
			// Required to initialize variables
			InitializeComponent();
            LayoutRoot.DataContext = this;
            Variables = new ObservableCollection<S8Variable>();
		}


        /// <summary>
        /// Get the list of variables that we are showing.
        /// </summary>
        private ObservableCollection<S8Variable> Variables
        {
            get { return (ObservableCollection<S8Variable>)GetValue(VariablesProperty); }
            set { SetValue(VariablesProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Variables.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty VariablesProperty =
            DependencyProperty.Register("Variables", typeof(ObservableCollection<S8Variable>), typeof(RandomVariableList), new PropertyMetadata(null));

        /// <summary>
        /// Add a variable to the list! Duplicates aren't allowed.
        /// </summary>
        /// <param name="sv"></param>
        public void AddVariable(S8Variable sv)
        {
            var alreadyThere = (from v in Variables
                                where v.Path == sv.Path
                                select v).FirstOrDefault();
            if (alreadyThere != null)
            {
                Variables.Remove(alreadyThere);
            }
            Variables.Add(sv);

            OnVariableAdded(sv);
        }

        /// <summary>
        /// Fired when the variable list gets updated.
        /// </summary>
        private void OnVariableAdded(S8Variable v)
        {
            if (VariableAdded != null)
            {
                VariableAdded(v);
            }
        }

        /// <summary>
        /// User is dropping a variable on us - we should see if we like it1
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        private bool DragTargetBehavior_DropObjectOK(object sender, Behaviors.DragDropDataEventArgs args)
        {
            return args.sourceElement is NamedValue
                && !(args.sourceElement as NamedValue).ReadOnly;
        }

        /// <summary>
        /// Ok - we have something new - stash it!
        /// </summary>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        private void DragTargetBehavior_DropObject(UIElement arg1, UIElement arg2)
        {
            NamedValue nv = arg1 as NamedValue;
            if (nv != null)
            {
                AddVariable(new UniformS8Variable(nv.Value) { Path = nv.Path, MinValue = nv.Value * 0.9, MaxValue = nv.Value * 1.1 });
            }
        }

        /// <summary>
        /// User wants to clear out all the times we have in the list.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ClearVariableList(object sender, System.Windows.RoutedEventArgs e)
        {
            Variables.Clear();
            OnVariablesCleared();
        }

        /// <summary>
        /// Called to fire the cleared vars dude.
        /// </summary>
        private void OnVariablesCleared()
        {
            if (VariablesCleared != null)
            {
                VariablesCleared();
            }
        }
	}
}